package cn.piesat.filter;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * @author: demo
 * @date: 2020年7月2日
 * @Document : 记录日志工具类
 */
public class RecordTool {
	private static Logger log = LoggerFactory.getLogger(RecordTool.class);

	private static final String MEDIA_APPLICATION = "application";
	private static final String MEDIA_APPLICATION_JSON = "json";
	private static final String MEDIA_APPLICATION_FORM_URLENCODED = "x-www-form-urlencoded";
	private static final String MEDIA_APPLICATION_XML = "xml";
	private static final String MEDIA_APPLICATION_ATOMXML = "atom+xml";
	private static final String MEDIA_APPLICATION_RSSXML = "rss+xml";
	private static final String MEDIA_APPLICATION_TEXT = "text";

	/**
	 * 获取请求体内容
	 * 
	 * @param headers
	 * @return
	 */
	public static Charset getCharsetRecord(HttpHeaders headers) {
		if (headers.getContentLength() > 0) {
			MediaType contentType = headers.getContentType();
			if (contentType == null) {
				log.debug("无法获取请求体 !");
				return null;
			} else if (!isSupportRecordType(contentType)) {
				log.debug("不支持记录的请求类型");
				return null;
			} else {
				return getMediaTypeCharset(contentType);
			}
		} else {
			return null;
		}
	}

	/**
	 * 获取请求类型
	 * 
	 * @param mediaType
	 * @return
	 */
	public static Charset getMediaTypeCharset(@Nullable MediaType mediaType) {
		if (mediaType != null && mediaType.getCharset() != null) {
			return mediaType.getCharset();
		} else {
			return StandardCharsets.UTF_8;
		}
	}

	/**
	 * 
	 * @param contentType
	 * @return
	 */
	public static boolean isSupportRecordType(MediaType contentType) {
		String type = contentType.getType();
		String subType = contentType.getSubtype();

		if (MEDIA_APPLICATION.equals(type)) {
			return MEDIA_APPLICATION_JSON.equals(subType) || MEDIA_APPLICATION_FORM_URLENCODED.equals(subType)
					|| MEDIA_APPLICATION_XML.equals(subType) || MEDIA_APPLICATION_ATOMXML.equals(subType)
					|| MEDIA_APPLICATION_RSSXML.equals(subType);
		} else if (MEDIA_APPLICATION_TEXT.equals(type)) {
			return true;
		}
		// 暂时不记录form
		return false;
	}

	/**
	 * 获取客户端IP
	 * 
	 * @param request ServerHttpRequest
	 * @return 客户端IP
	 */
	public static String getClientIp(@NonNull ServerHttpRequest request) {
		String result = null;
		HttpHeaders headers = request.getHeaders();
		if (headers.getFirst("X-Forwarded-For") != null) {
			result = headers.getFirst("X-Forwarded-For");
		} else if (headers.getFirst("Proxy-Client-IP") != null) {
			result = headers.getFirst("Proxy-Client-IP");
		} else if (headers.getFirst("WL-Proxy-Client-IP") != null) {
			result = headers.getFirst("WL-Proxy-Client-IP");
		} else if (headers.getFirst("HTTP_CLIENT_IP") != null) {
			result = headers.getFirst("HTTP_CLIENT_IP");
		} else if (headers.getFirst("X-Real-IP") != null) {
			result = headers.getFirst("X-Real-IP");
		}
		if (StringUtils.isBlank(result) || "unknown".equalsIgnoreCase(result)) {
			result = Objects.requireNonNull(request.getRemoteAddress()).getAddress().getHostAddress();
		}

		return result;
	}
}
